package com.chenxiao.mybatisplus.aop.aspect;

/**
 * @Author: Chenxiao
 * @Date: 2022-07-31 22:48
 * @Description: LogAspect
 */

import com.chenxiao.mybatisplus.aop.entity.LogRecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.function.Supplier;

/**
 * 日志切面类
 */
@Slf4j
@Aspect
@Component
public class LogAspect {



    /**
     * 切点
     */
    @Pointcut("@annotation(com.chenxiao.mybatisplus.aop.annotation.WebLog)")
    private void LogAspectPointcut(){};

    /**
     * 前置通知
     * 通知方法会在目标方法调用之前执行
     * @param joinPoint 连接点
     */
    @Before("LogAspectPointcut()")
    public void doBefore(JoinPoint joinPoint) {
        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time=sim.format(new Date());
        LogRecord logRecord = new LogRecord();
        logRecord.setIp(request.getRemoteAddr());
        logRecord.setMethod(request.getMethod());
        logRecord.setUrl(request.getRequestURL().toString());
        logRecord.setStartTime(time);
        logRecord.setUserName("测试用户");

        //输出日志
        log.warn(logRecord.toString());

    }
    /**
     * 声明环绕通知
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("LogAspectPointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("====================");
        long begin = System.nanoTime();
        Object obj = pjp.proceed();
        long end = System.nanoTime();

        log.info("调用Mapper方法：{}，参数：{}，执行耗时：{}纳秒，耗时：{}毫秒",
                pjp.getSignature().toString(), Arrays.toString(pjp.getArgs()),
                (end - begin), (end - begin) / 1000000);
        return obj;
    }
}